const Service = require('egg').Service
const axios = require('axios')

class ConfigService extends Service {
  // 根据type获取配置
  async getConfigByType(type) {
    const { ctx } = this

    const doc = await ctx.model.Config.findOne({
      configType: type.replace('-', '_'),
      isOpen: true,
    })

    if (!doc) throw '无效配置'

    return {
      configId: doc.id,
      ...doc.config,
    }
  }

  async getConfig(configType) {
    const { ctx } = this

    const doc = await ctx.model.Config.findOne({
      configType,
    })

    return {
      ...doc.config,
    }
  }

  /**
   * 获取微信小程序access_token
   * @param {String} appId
   * @param {String} secret
   */
  async getMiniProgramAccessToken(appId, secret) {
    const { config } = this

    // 非正式环境，从中控服务器获取access_token
    if (config.env != 'prod' && config.controlServer) {
      return await axios.get(config.controlServer + '/api/wechat/mini/access-token').then((res) => {
        if (res.data.code == 0) {
          return res.data.data.accessAoken
        } else throw '中控服务器异常'
      })
    }

    if (!appId) appId = config.wechat.miniProgram.appId
    if (!secret) secret = config.wechat.miniProgram.secret

    return this.getAccessToken(appId, secret)
  }

  /**
   * 获取微信公众号access_token
   * @param {String} appId
   * @param {String} secret
   * */
  async getAccessToken(appId, secret) {
    const { config, app } = this
    const { wechatApi } = app

    // 非正式环境，从中控服务器获取access_token
    if (config.env != 'prod' && config.controlServer) {
      return await axios.get(config.controlServer + '/api/wechat/mp/access-token').then((res) => {
        if (res.data.code == 0) {
          return res.data.data.accessAoken
        } else throw '中控服务器异常'
      })
    }

    if (!appId) appId = config.wechat.appId
    if (!secret) secret = config.wechat.secret

    const cacheKey = `wechat_access_token_${appId}`

    let accessAoken = await this.service.cache.get(cacheKey)

    // 以获取accessAoken，并未过期
    if (accessAoken) return accessAoken

    // 获取accessAoken及过期时间
    let expire
    await wechatApi.miniProgram
      .getAccessToken({
        appId,
        secret,
      })
      .then((res) => {
        accessAoken = res.access_token
        expire = res.expires_in * 1000
      })

    // 缓存配置
    await this.service.cache.set(cacheKey, accessAoken, expire)

    return accessAoken
  }

  /**
   * 获取微信公众号access_token
   *
   * 微信 JS 接口签名校验工具
   * https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
   *
   * @param {String} appId
   * @param {String} secret
   * */
  async getJsapiTicket(appId, secret, accessToken) {
    const { config } = this
    const { wechatApi } = this.app

    // 非正式环境，从中控服务器获取access_token
    if (config.env != 'prod' && config.controlServer) {
      return await axios.get(config.controlServer + '/api/wechat/mp/jsapi-ticket').then((res) => {
        if (res.data.code == 0) {
          return res.data.data.jsapiTicket
        } else throw '中控服务器异常'
      })
    }

    if (!appId) appId = config.wechat.appId
    if (!secret) secret = config.wechat.secret

    const cacheKey = `wechat_jsapi_ticket_${appId}`
    let jsapiTicket = await this.service.cache.get(cacheKey)

    console.log('jsapiTicket', jsapiTicket)

    // 使用缓存
    if (jsapiTicket) {
      return jsapiTicket
    } else {
      if (!accessToken) accessToken = await this.getAccessToken(appId, secret)

      let expire
      await wechatApi.mp
        .gettJsApiTicket({
          appId,
          secret,
          accessToken,
        })
        .then((res) => {
          jsapiTicket = res.ticket
          expire = res.expires_in * 1000
        })

      // 缓存配置
      await this.service.cache.set(cacheKey, jsapiTicket, expire)

      return jsapiTicket
    }
  }
}

module.exports = ConfigService
